<?php
/**
 * User: @lixu
 * Date: 2019-06-28
 * Time: 11:44
 */

namespace Biz\service\esSearch;

use Biz\model\trade\Order as mOrder;
use Biz\model\trade\OrderGoods as mOrderGoods;
use Biz\model\trade\OrderRefund as mOrderRefund;
use Biz\model\trade\OrderPackage as mOrderPackage;
use Biz\model\trade\OrderExtend as mOrderExtend;
use Biz\model\theParagraph\Store as mStore;
use Biz\module\Search\OrderSearch;
use Doraemon\amqp\Queue;
use Doraemon\tools\Log;
use Biz\tools\FormatDate;

class Order
{
    // 来源
    const SOURCE_APP = 'app';
    const SOURCE_SHOP_ADMIN = 'shop_admin';
    const SOURCE_THE_PARAGRAPH = 'the_paragraph';

    // 场景
    const SCENES_SHOP_ADMIN_ORDER = 'shop_admin_order'; // 商城管理后台订单列表
    const SCENES_SELLER_ORDER = 'seller_order'; // 商家管理后台订单列表
    const SCENES_APP_ORDER = 'app_order_list'; // app订单列表
    const SCENES_APP_ORDER_STATUS_COUNT = 'app_order_status_count'; // app订单列表
    const SCENES_THE_PARAGRAPH_ORDER = 'the_paragraph_order'; // 节选小程序订单列表


    public static function getList(array $where = [], $scenes = null, $sortType = 1, $page = 1, $pageSize = 20,  $field = ['id'])
    {
        $result = ['total' => 0, 'is_over' => 1, 'rows' => []];

        if(is_null($scenes)) {
            return $result;
        } else {
            $where['scenes'] = $scenes;
        }

        if(!isset($where['ORDER'])) {
            $where['ORDER'] = self::sortTypeMapping($sortType);
        }

        $params['query'] = json_encode($where, JSON_UNESCAPED_UNICODE);

        if(is_array($field)) {
            $params['fl'] = implode(",", $field);
        } else {
            $params['fl'] = $field;
        }

        $params['page'] = $page;
        $params['page_size'] = $pageSize;

        $result = OrderSearch::getList($params);

        if(isset($result['data'])) {
            $result = $result['data'];
            $list['total'] = $result['hits']['total'];
            $list['rows'] = $result['hits']['total'] ? self::formatOrderList($result['hits']['hits'], $field) : [];
            $list['is_over'] = 1;
            if (isset($result['hits']['hits']) && (count($result['hits']['hits']) >= $pageSize)) {
                $list['is_over'] = 0;
            }
            if(isset($result['aggregations'])) {
                $list['aggregations'] = $result['aggregations'];
            }
            return $list;
        } else {
            return ['total' => 0, 'is_over' => 1, 'rows' => []];
        }
    }

    private static function sortTypeMapping($sortType)
    {
        $sortMapping = [
            1 => ['addtime' => 'DESC'],
            2 => ['addtime' => 'ASC'],
        ];

        return $sortMapping[$sortType];
    }

    /**
     *  上层代码控制要同步的数据
     * @param $orderInfo
     * @return array|bool
     */
    public static function saveByOrderId($orderInfo)
    {
        if(!$orderInfo['id']) {
            return false;
        }

        $result = OrderSearch::save($orderInfo);

//        if($result['code'] != 1) {
//            Queue::insertQueue("queue/Wechatnotice/toTag", [
//                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_SYSTEM,
//                "content" => 'goods表 同步数据失败 ' . $result
//            ], Queue::QUEUE_BIZ);
//        }

        return $result;
    }

    /**
     * 监听binlog同步数据
     * @param $list
     */
    public static function syncSave($list)
    {
        $info = [];
        switch ($list['table']) {
            case 'order' :
                $info = self::formatOrderInfo($list['data']);
                break;
            case 'order_goods' :
                $info = self::formatOrderGoodsInfo($list['data']);
                break;
            case 'order_refund' :
                $info = self::formatOrderRefundInfo($list['data']);
                break;
            case 'order_package' :
                $info = self::formatOrderPackageInfo($list['data']);
                break;
            case 'order_extend' :
                $info = self::formatOrderExtendInfo($list['data']);
                break;
            case 'customize_pay_way' :
                $info = self::formatCustomizePayWayInfo($list['data']);
                break;
        }
        $result = OrderSearch::save($info);

        Log::debug('order-debug', $result);

        if($result['code'] != 1) {
            Queue::insertQueue("queue/Wechatnotice/toTag", [
                "totag" => \Biz\pockets\constInterface\BizWechatTagConfig::TAG_BIZ_RD_SYSTEM,
                "content" => $list['table'] . '表 同步数据失败 ' . $result,
                'addtime' => date("Y-m-d H:i:s")
            ], Queue::QUEUE_BIZ);
        }
    }

    private static function formatOrderInfo($data)
    {
        $info = [
            'id' => $data['id'],
            'order_no' => $data['order_no'],
            'status' => $data['status'],
            'goods_amount' => $data['goods_amount'],
            'pay_amount' => $data['pay_amount'],
            'from_source' => $data['from_source'],
            'order_type' => $data['order_type'],
            'shop_id' => $data['shop_id'],
            'uid' => $data['uid'],
            'buy_num' => $data['buy_num'],
            'coupon_id' => $data['coupon_id'],
            's_coupon_id' => $data['s_coupon_id'],
            'pay_way' => $data['pay_way'],
            'pay_no' => $data['pay_no'],
            'consignee_phone' => $data['consignee_phone'],
            'consignee_name' => $data['consignee_name'],
            'express_no' => $data['express_no'],
            'express_company' => $data['express_company'],
            'is_commented' => $data['is_commented'],
            'addtime' => FormatDate::formatDate($data['addtime']),
            'pay_time' => $data['pay_time'] == '0000-00-00 00:00:00' ? '0000-01-01 00:00:00' : FormatDate::formatDate($data['pay_time']),
            'confirm_time' => $data['confirm_time'] == '0000-00-00 00:00:00' ? '0000-01-01 00:00:00' : FormatDate::formatDate($data['confirm_time']),
            'delivery_time' => $data['delivery_time'] == '0000-00-00 00:00:00' ? '0000-01-01 00:00:00' : FormatDate::formatDate($data['delivery_time']),
            'refunding_status' => $data['refunding_status'],
        ];

        return $info;
    }

    private static function formatOrderGoodsInfo($data)
    {
        $info = [];
        $orderId = self::getOrderIdByOrderNo($data['order_no']);
        $orderGoodsList = mOrderGoods::select_master(['goods_id', 'title', 'category_id', 'second_category_id', 'sku_id'], ['order_no' => $data['order_no']]);
        foreach ($orderGoodsList as $orderGoods) {
            $info[] = [
                'goods_id' => $orderGoods['goods_id'],
                'sku_id' => $orderGoods['sku_id'],
                'title' => $orderGoods['title'],
                'category_id' => $orderGoods['category_id'],
                'second_category_id' => $orderGoods['second_category_id']
            ];
        }

        return ['id' => $orderId, 'order_goods' => $info];
    }

    private static function formatOrderRefundInfo($data)
    {
        $info = [];
        $orderId = self::getOrderIdByOrderNo($data['order_no']);
        $orderRefundList = mOrderRefund::select_master(['status', 'refund_order_no'], ['order_no' => $data['order_no']]);
        foreach ($orderRefundList as $orderRefund) {
            $info[] = [
                'refund_status' => $orderRefund['status'],
                'refund_order_no' => $orderRefund['refund_order_no']
            ];
        }

        return ['id' => $orderId, 'order_refund' => $info];
    }

    private static function formatOrderPackageInfo($data)
    {
        $info = [];
        $orderId = self::getOrderIdByOrderNo($data['order_no']);
        $orderPackageList = mOrderPackage::select_master(['express_no', 'express_company'], ['order_no' => $data['order_no']]);
        foreach ($orderPackageList as $orderPackage) {
            $info[] = [
                'express_no' => $orderPackage['express_no'],
                'express_company' => $orderPackage['express_company']
            ];
        }

        return ['id' => $orderId, 'order_package' => $info];
    }

    private static function formatOrderExtendInfo($data)
    {
        $info['store_name'] = mStore::get('abbr', ['id' => $data['store_id']]);
        $info['store_id'] = $data['store_id'];
        $orderId = self::getOrderIdByOrderNo($data['order_no']);
        return ['id' => $orderId, 'order_extend' => $info];
    }

    private static function formatCustomizePayWayInfo($data)
    {
        $orderId = self::getOrderIdByOrderNo($data['order_no']);
        $info['pay_type'] = $data['pay_type'];
        return ['id' => $orderId, 'customize_pay_way' => $info];
    }

    private static function getOrderIdByOrderNo($orderNo)
    {
        return mOrder::get('id', ['order_no' => $orderNo]);
    }

    private static function formatOrderList($orderList, $field)
    {
        $list = [];
        foreach ($orderList as $value) {
            if(!is_array($field)) {
                $list[] = $value['_source'][$field];
            } else if(count($field) == 1) {
                $list[] = $value['_source'][current($field)];
            } else {
                $list[] = $value['_source'];
            }
        }

        return $list;
    }
}